package store

import "gorm.io/gorm"

type OAuthStore interface {
	/**
	  客户端
	*/

	// SelClient 第一次查询client，返回客户端数据
	SelClient(clientIdReq string) (registerId, clientId, clientName, clientSecret, grantTypes, redirectUri, scope string, codeExp, tokenExp, refreshTokenExp int64, err error)
	/**
	  授权
	*/

	// SaveAuthorization 授权请求
	SaveAuthorization(registerId, userName, grantTypes, attributes, state, codeChallenge, codeChallengeMethod string) error

	// SelAuthorizationInfo 查询上面的授权信息，已修改为存储client的注册Id
	SelAuthorizationInfo(stateReq, username string) (aId, attributes string, err error)

	/**
	  认证
	*/

	// SaveAuthentication 第二次授权页面，授权确定后，保存确认好的授权内容，只需要返回是否成功，aId是授权信息里的随机Id，作为主键
	SaveAuthentication(aId, code, scope string, codeExp int64) error

	// SelAuthentication 根据code查询授权的数据，已修改为存储client的注册Id
	SelAuthentication(code string) (aId, username, att, codeChallenge, scope string, codeExp int64, err error)

	/**
	  Token
	*/

	// SaveToken 保存token，保存到上面一样的授权信息表中，需要过期时间
	SaveToken(aId, token, refreshToken, openId, scope string, tokenExp, refreshTokenExp int64) error

	// SelToken 查询token用于刷新，注销
	SelToken(token string) (aId, clientId, username, refreshToken string, err error)

	/**
	  刷新token
	*/

	// SelRefreshToken 查询刷新token，需要返回一些用户信息，客户端信息，授权范围，需要返回openid，这里使用refreshToken作为唯一标识，返回授权信息随机Id，不然会更新重复
	SelRefreshToken(refreshToken string) (aId, clientId, username, scope, openId string, refreshTokenExp int64, err error)

	/**
	  注销token
	*/

	// DelAuthentication 注销token，直接删除aid
	DelAuthentication(aId string) error

	// SelScopeTag 根据scope tag查询scope
	SelScopeTag(tag string) (id int, name, tagDb, permission, remarks string, err error)

	/**
	  consent，未完成
	*/

	// SelConsentInfo 新增的功能
	SelConsentInfo(registerId, username string) (scope string, err error)
	// SaveConsent 保存一下功能
	SaveConsent(registerId, username, scope string) (err error)

	// SelUserScopeTag 查询用户是否有scope授权
	SelUserScopeTag(username string) (scope string, err error)
}

type oauthStoreImpl struct {
	db *gorm.DB
}

func NewOAuthStore(d *gorm.DB) OAuthStore {
	return &oauthStoreImpl{
		db: d,
	}
}
